package xdu.lz.netty.a_introduction.second_socket;

import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoop;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.logging.LogLevel;
import io.netty.handler.logging.LoggingHandler;

/**
 * @Author Badribbit
 * @create 2019/4/14 21:46
 */

/**
 * nett即可以做客户端也可以做服务端
 * 一对一交互
 */
public class MyServer {
    public static void main(String[] args) throws  Exception{
        //事件循环组
        //只是完成了一些参数的赋值，并没有开启什么东西。 参数是开启线程的个数，不传则是CPU核数*2

        EventLoopGroup bossGroup=new NioEventLoopGroup(1);
        EventLoopGroup workerGroup=new NioEventLoopGroup();
        try{
            ServerBootstrap serverBootstrap = new ServerBootstrap();

            serverBootstrap.group(bossGroup,workerGroup).channel(NioServerSocketChannel.class).

                    handler(new LoggingHandler(LogLevel.DEBUG)).  //初始化时候会被 加入到 ServerBootstrapAcceptor   Reactor中的Acceptor
                    childHandler(new MyServerInitizlizer());

            System.out.println(0);
            //sync表示 bind完成后再返回ChannelFuture，不加的话执行会往下执行code。可能会出问题
            ChannelFuture channelFuture = serverBootstrap.bind(8899).sync();

            System.out.println(1);


           // 服务端管道[绑定端口所开启的管道]关闭的监听器并同步阻塞,直到channel关闭,线程才会往下执行,结束进程；

            //主线程执行到这里就 wait 子线程结束，子线程才是真正监听和接受请求的，子线程就是Netty启动的监听端口的线程；

            //即closeFuture()是开启了一个channel的监听器，负责监听channel是否关闭的状态，如果未来监听到channel关闭了，
            //子线程才会释放，syncUninterruptibly()让主线程同步等待子线程结果。

            //.channel.close()才是主动关闭通道的方法。

            channelFuture.channel().closeFuture().sync();
//            这里执行不到
            System.out.println(2);
        }finally {
            System.out.println(3);
            bossGroup.shutdownGracefully();
            workerGroup.shutdownGracefully();
        }
    }
}
